export default {}


// 类装饰器
// 🚀 更类型安全的写法     你甚至可以返回一个扩展后的类
function Logger<T extends { new(...args: any[]): {} }>(constructor: T) {
    (constructor as any).ttype = "我是类装饰器"
    // 这是一个新类，它继承了原始类，但它本身有自己的 prototype，被下面的覆盖了
    constructor.prototype.user = function () {
        console.log("我是zks")
    };
    console.log("类的名称为", (constructor as any).name)
    return class extends constructor {
        static type = 'Entity';

        constructor(...args: any) {
            super(args);
        }

        student() {
            console.log("这是一个实例方法")
        }
    };
}

// function Logger(constructor: Function) {
//     console.log("类的名称为", (constructor as any).name)
//     ///这个constructor是一个构造函数相当于就是Person你可以在上面挂载静态属性和实例方法
//     constructor.prototype.zks = function () {
//         console.log("这是一个实例方法")
//     };
//     (constructor as any).type = 'Entity';
// }

@Logger
class Person {
    constructor() {
        console.log('A')
    }
}

const p = new Person()
console.log(p)


// 工厂函数 借助函数返回类装饰器  可以进行ts提示
function TestDe(flag: boolean) {
    return function <T extends { new(...args: any[]): {} }>(constructor: T) {
        if (flag) {
            return class extends constructor {
                name = "zks"
                age = 18

                show() {
                    console.log(this.name)
                }
            };
        } else {
            return class extends constructor {
                unreachable() {
                    console.log("这是不可访问的")
                }
            };
        }
    }

}

const TestPerson = TestDe(true)(class Person {
    uname: string = "再找找看是"

    constructor(uname: string) {
        this.uname = uname
    }
})


const testP = new TestPerson("江苏无锡");
console.log(testP)  //class_2 { uname: '江苏无锡', name: 'zks', age: 18 }
